package com.chenfan.magic.tags;

import com.chenfan.magic.base.R;
import com.chenfan.magic.base.S;
import com.chenfan.magic.entity.MQLModel;
import com.chenfan.magic.entity.TTLDetailModel;
import com.chenfan.magic.entity.TTLModel;
import com.chenfan.magic.utils.StringKit;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.List;

/**
 * @author 周夕
 * @date 2020-02-26 21:14
 */
@Slf4j
public class __TagProvider {

    /**
     * 最终标签
     */
    public static final String RUNTIME_TAG_NAME = "textarea";
    public static final String RUNTIME_TAG_ATTR = "magic-type";

    /**
     * 解析器缓存池
     */
    private static List<String> providerTagNamePool = Lists.newArrayList();

    static {
        providerTagNamePool.add(TagHttp.tagNames);
        providerTagNamePool.add(TagRedis.tagNames);
        providerTagNamePool.add(TagScript.tagNames);
        providerTagNamePool.add(TagShell.tagNames);
        providerTagNamePool.add(TagTemplate.tagNames);
        providerTagNamePool.add(TagValidate.tagNames);
        providerTagNamePool.add(TagResolve.tagNames);
        providerTagNamePool.add(TagEmail.tagNames);
        providerTagNamePool.add(TagSms.tagNames);
        providerTagNamePool.add(TagRobot.tagNames);
    }

    /**
     * 预处理: 为了 jsonp 解析时候不出现自动忽略 => 先转为 textarea 处理.
     *
     * @param context
     * @return
     */
    public static String preProvider(String context) {
        for (String tagName : providerTagNamePool) {
            context = context
                    .replace("<" + tagName + ">", "<" + RUNTIME_TAG_NAME + " " + RUNTIME_TAG_ATTR + "=\"" + tagName + "\">")
                    .replace("<" + tagName + " ", "<" + RUNTIME_TAG_NAME + " " + RUNTIME_TAG_ATTR + "=\"" + tagName + "\" ")
                    .replace("</" + tagName + ">", "</" + RUNTIME_TAG_NAME + ">");
        }
        log.info(context);
        return context;
    }

    /**
     * jsonp 解析处理: 一级解析语法
     *
     * @param context
     * @return
     */
    public static R jsonpProvider(String context, TTLModel ttlModel) {
        TTLDetailModel ttlDetailModelJsonp = new TTLDetailModel();
        ttlDetailModelJsonp.start("jsonp");

        context = preProvider(context);
        //以标签id为串, 排序.
        MQLModel mqlModel = new MQLModel();
        Document doc = Jsoup.parse(context, "GBK");

        Elements runtimeTags = doc.getElementsByTag(RUNTIME_TAG_NAME);
        int index = 0;
        for (Element runtimeTag : runtimeTags) {
            index++;
            switch (runtimeTag.attr(RUNTIME_TAG_ATTR)) {
                case "robot":
                    TagRobot robotModel = new TagRobot(runtimeTag, index);
                    mqlModel.addRobot(robotModel);
                    break;
                case "sms":
                    TagSms smsModel = new TagSms(runtimeTag, index);
                    mqlModel.addSms(smsModel);
                    break;
                case "email":
                    TagEmail emailModel = new TagEmail(runtimeTag, index);
                    mqlModel.addEmail(emailModel);
                    break;
                case "resolve":
                    TagResolve resolveModel = new TagResolve(runtimeTag, index);
                    mqlModel.addResolve(resolveModel);
                    break;
                case "validate":
                    TagValidate validateModel = new TagValidate(runtimeTag, index);
                    mqlModel.addValidate(validateModel);
                    break;
                case "template":
                    TagTemplate templateModel = new TagTemplate(runtimeTag, index);
                    mqlModel.addTemplate(templateModel);
                    break;
                case "script":
                    if (StringKit.isBlank(runtimeTag.attr("language")) && StringKit.isBlank(runtimeTag.attr(":language"))) {
                        return S.fail(S.IDC_RESOLVER_SCRIPT_LANGUAGE_REQUIRED);
                    }
                    TagScript scriptModel = new TagScript(runtimeTag, index);
                    mqlModel.addScript(scriptModel);
                    break;
                case "shell":
                    TagShell commandModel = new TagShell(runtimeTag, index);
                    mqlModel.addShell(commandModel);
                    break;
                case "http":
                    if (StringKit.isBlank(runtimeTag.attr("url")) && StringKit.isBlank(runtimeTag.attr(":url"))) {
                        return S.fail(S.IDC_RESOLVER_HTTP_URL_REQUIRED);
                    }
                    TagHttp httpModel = new TagHttp(runtimeTag, index);
                    mqlModel.addHttp(httpModel);
                    break;
                case "redis":
                    if (StringKit.isBlank(runtimeTag.attr("key")) && StringKit.isBlank(runtimeTag.attr(":key"))) {
                        return S.fail(S.IDC_RESOLVER_REDIS_KEY_REQUIRED);
                    }
                    TagRedis redisModel = new TagRedis(runtimeTag, index);
                    mqlModel.addRedis(redisModel);
                    break;
                default:
                    return S.fail(S.IDC_RESOLVER_UNKNOW_TAG);
            }
        }
        mqlModel.sort();
        ttlDetailModelJsonp.end();
        ttlModel.getResolver().put(ttlDetailModelJsonp);
        ttlModel.setJsonpResolver(ttlDetailModelJsonp);
        return R.success().put(mqlModel);
    }
}
